package test;



import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import dsa.LinkedList;
import dsa.ListIterator;


public class JasonFidukTest {

	LinkedList testList;
	ListIterator testIterator;

	@Before
	public void setUp() throws Exception {
		testList = new LinkedList();
		testList.addFirst(56.4);
		testList.addLast("Jason");
		testList.addFirst("Hello");
		testIterator = testList.listIterator(0);
		// List goes Hello, 56.4, Jason
	}

	@Test
	public void testAddLast() {
		testList.addLast("Last");
		assertTrue(testList.getLast().equals("Last"));
	}

	@Test
	public void testAddFirst() {
		testList.addFirst("First");
		assertTrue(testList.getFirst().equals("First"));
	}

	@Test
	public void testAllFirst() {
		assertTrue(testList.getFirst().equals("Hello"));
		testList.removeFirst();
		assertTrue(testList.getFirst().equals(56.4));
	}

	@Test
	public void testAllLast() {
		assertTrue(testList.getLast().equals("Jason"));
		testList.removeLast();
		assertTrue(testList.getLast().equals(56.4));
	}

	@Test
	public void testSize() {
		assertTrue(testList.size() == 3);
		testList.removeLast();
		assertTrue(testList.size() == 2);
		testList.addLast("cake");
		testList.addLast("candy");
		assertTrue(testList.size() == 4);
		testList.addFirst(010);
		testList.addFirst(101);
		assertTrue(testList.size() == 6);
		testList.removeFirst();
		testList.remove(1);
		assertTrue(testList.size() == 4);
	}

	@Test
	public void testGet() {
		assertTrue(testList.get(0).equals("Hello"));
		assertTrue(testList.get(1).equals(56.4));
		assertTrue(testList.get(2).equals("Jason"));
		testList.addLast(304);
		assertTrue(testList.get(3).equals(304));
		assertFalse(testList.remove(3).equals(testList.get(3)));
	}

	@Test
	public void testRemove() {
		assertTrue(testList.remove(1).equals(56.4));
		testList.addLast("Object");
		// List so far is Hello, Jason, Object
		assertTrue(testList.removeFirst().equals("Hello"));
		testList.addFirst(-100);
		testList.addLast("Soon last object");
		testList.addLast("Temp last object");
		// List so far is -100, Jason, Object, soon last object, temp last
		// object.
		assertTrue(testList.removeLast().equals("Temp last object"));
		assertTrue(testList.getLast().equals("Soon last object"));
	}

	@Test
	public void testToArray() {
		Object[] array = testList.toArray();
		assertTrue(array[0].equals("Hello"));
		assertTrue(array[1].equals(56.4));
		assertTrue(array[2].equals("Jason"));
	}

	@Test
	public void testSet() {
		testList.set(2, "New Object");
		testList.set(0, 100);
		// List so far is 100, 56.4, New Object.
		assertTrue(testList.get(0).equals(100));
		assertTrue(testList.get(2).equals("New Object"));
	}

	@Test
	public void testIndexOf() {
		assertTrue(testList.indexOf("This doesnt exist") == -1);

		assertTrue(testList.indexOf("Jason") == 2);

	}

	@Test
	public void testContains() {
		assertFalse(testList.contains("This doesnt exist"));
		assertTrue(testList.contains(56.4));
		testList.remove(1);
		assertFalse(testList.contains(56.4));

	}

	@Test
	public void testClone() {
		LinkedList clone = (LinkedList) testList.clone();
		assertTrue(testList.get(0).equals(clone.get(0)));
		assertTrue(testList.get(1).equals(clone.get(1)));
		assertTrue(testList.get(2).equals(clone.get(2)));

	}
	@Test
	public void testIteratorAdd() 
	{
		testIterator.add("foo");
		assertTrue(testIterator.previous().equals("foo"));
		testIterator.next();
		assertTrue(testIterator.next().equals("Hello"));
		testIterator.add("bar");
		assertTrue(testIterator.previous().equals("bar"));
		testIterator.next();
		assertTrue(testIterator.next().equals(56.4));
	}
	@Test
	public void testIteratorHasNext() 
	{
		assertTrue(testIterator.hasNext());
		testIterator.next();
		assertTrue(testIterator.hasNext());
		testIterator.next();
		assertTrue(testIterator.hasNext());
		testIterator.next();
		assertFalse(testIterator.hasNext());
		
	}
	@Test
	public void testIteratorHasPrevious() 
	{
		testIterator.next();
		testIterator.next();
		testIterator.next();
		assertTrue(testIterator.hasPrevious());
		testIterator.previous();
		assertTrue(testIterator.hasPrevious());
		testIterator.previous();
		assertTrue(testIterator.hasPrevious());
		testIterator.previous();
		assertFalse(testIterator.hasPrevious());
	}
	@Test
	public void testIteratorNext() 
	{
		assertTrue(testIterator.next().equals("Hello"));
		assertTrue(testIterator.next().equals(56.4));
		assertTrue(testIterator.next().equals("Jason"));
		assertTrue(testIterator.next()== null);
	}
	@Test
	public void testIteratorNextIndex() 
	{
		assertTrue(testIterator.nextIndex() == 0);
		testIterator.next();
		assertTrue(testIterator.nextIndex() == 1);
		testIterator.next();
		assertTrue(testIterator.nextIndex() == 2);
		testIterator.previous();
		assertTrue(testIterator.nextIndex() == 1);
	}
	@Test
	public void testIteratorPrevious() 
	{
		testIterator.next();
		testIterator.next();
		testIterator.next();
		assertTrue(testIterator.previous().equals("Jason"));
		assertTrue(testIterator.previous().equals(56.4));
		assertTrue(testIterator.previous().equals("Hello"));
	}
	@Test
	public void testIteratorPreviousIndex() 
	{
		testIterator.next();
		testIterator.next();
		testIterator.next();
		assertTrue(testIterator.previousIndex() == 2);
		testIterator.previous();
		assertTrue(testIterator.previousIndex() == 1);
		testIterator.next();
		assertTrue(testIterator.previousIndex() == 2);
		testIterator.previous();
		testIterator.previous();
		assertTrue(testIterator.previousIndex() == 0);
		testIterator.previous();
		assertTrue(testIterator.previousIndex() == -1);
	}
	@Test
	public void testIteratorRemove() 
	{
		testIterator.next();
		testIterator.remove();
		assertFalse(testIterator.hasPrevious());
		assertTrue(testIterator.next().equals(56.4));
	}
	@Test
	public void testIteratorSet() 
	{
		testIterator.next();
		testIterator.set("First");
		assertTrue(testIterator.previous().equals("First"));
	}
}
